package com.pig4cloud.pigx.robot.ws.collect;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.pig4cloud.pigx.common.customize.redis.utils.RedisUtils;
import com.pig4cloud.pigx.robot.entity.RobotConfig;
import com.pig4cloud.pigx.robot.mapper.RobotConfigMapper;
import com.pig4cloud.pigx.robot.rabbitmq.MQConstant;
import com.pig4cloud.pigx.robot.service.RobotConfigService;
import com.pig4cloud.pigx.robot.vo.RobotConfigVO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Slf4j
@Order(0)
@Component

public class FetchManager implements ApplicationRunner {

	private static  Map<String,String>  parsedata_biance= new HashMap<>();
	private static  Map<String,String>  parsedata_bitmex= new HashMap<>();
	private static  Map<String,String>  parsedata_ftx= new HashMap<>();
	private static  Map<String,String>  parsedata_gate= new HashMap<>();
	private static  Map<String,String>  parsedata_mexc= new HashMap<>();
	private static  Map<String,String>  parsedata_okx= new HashMap<>();

	private    long lasttime_binance  ;
	private   long lasttime_bitmex;
	private   long lasttime_ftx;
	private   long lasttime_gate;
	private   long lasttime_mexc;
	private   long lasttime_okx;

	public static final   int expire_millisecond = 10000;

	@Autowired
	private RedisTemplate redis;

	@Autowired
	private RabbitTemplate rabbitTemplate;

	@Autowired
	private RobotConfigService robotConfigService;

	@Autowired
	private RobotConfigMapper configMapper;
	public static List<RobotConfigVO> robotConfigList;
	public static String[] EXCHANGES = {"binance","bitmex","ftx","gate","mexc","okx"};
	@Override
	public void run(ApplicationArguments args ) throws Exception {
		log.info("fetch data init...");
		init();
	}
	private void init(){
		initSymbol();
		startFetch();
		flush_redis_data();
	}
	private void startFetch(){
		com.pig4cloud.pigx.robot.ws.collect.binance.WsManager.getInstance().init(this);
		com.pig4cloud.pigx.robot.ws.collect.bitmex.WsManager.getInstance().init(this);
		com.pig4cloud.pigx.robot.ws.collect.ftx.WsManager.getInstance().init(this);
		com.pig4cloud.pigx.robot.ws.collect.gate.WsManager.getInstance().init(this);
		com.pig4cloud.pigx.robot.ws.collect.mexc.WsManager.getInstance().init(this);
		com.pig4cloud.pigx.robot.ws.collect.okx.WsManager.getInstance().init(this);
	}
	private void reFetch(){
		com.pig4cloud.pigx.robot.ws.collect.binance.WsManager.getInstance().reConnection();
		com.pig4cloud.pigx.robot.ws.collect.bitmex.WsManager.getInstance().reConnection();
		com.pig4cloud.pigx.robot.ws.collect.ftx.WsManager.getInstance().reConnection();
		com.pig4cloud.pigx.robot.ws.collect.gate.WsManager.getInstance().reConnection();
		com.pig4cloud.pigx.robot.ws.collect.mexc.WsManager.getInstance().reConnection();
		com.pig4cloud.pigx.robot.ws.collect.okx.WsManager.getInstance().reConnection();
	}
	private void endFetch(){
		com.pig4cloud.pigx.robot.ws.collect.binance.WsManager.getInstance().onClose();
		com.pig4cloud.pigx.robot.ws.collect.bitmex.WsManager.getInstance().onClose();
		com.pig4cloud.pigx.robot.ws.collect.ftx.WsManager.getInstance().onClose();
		com.pig4cloud.pigx.robot.ws.collect.gate.WsManager.getInstance().onClose();
		com.pig4cloud.pigx.robot.ws.collect.mexc.WsManager.getInstance().onClose();
		com.pig4cloud.pigx.robot.ws.collect.okx.WsManager.getInstance().onClose();
	}
	private void initSymbol(){
		FetchManager.robotConfigList = configMapper.initRobotList();
		System.out.println(robotConfigList.size());
	}
	@RabbitListener(queues = MQConstant.QUEUE_ROBOT_SYMBOL_UPDATE)
	@RabbitHandler
	private void updateSymbol(){
		initSymbol();
		endFetch();

	}

	public  void setdata(String key,String v){
		if(key.indexOf("binance") > -1){
			parsedata_biance.put(key,v);
			lasttime_binance = System.currentTimeMillis();

		}else if (key.indexOf("bitmex") > -1){
			parsedata_bitmex.put(key,v);
			lasttime_bitmex = System.currentTimeMillis();

		}else if(key.indexOf("ftx") > -1){
			parsedata_ftx.put(key,v);
			lasttime_ftx = System.currentTimeMillis();

		}else if(key.indexOf("gate") > -1){
			parsedata_gate.put(key,v);
			lasttime_gate = System.currentTimeMillis();

		}else if(key.indexOf("mexc") > -1){
			parsedata_mexc.put(key,v);
			lasttime_mexc = System.currentTimeMillis();

		}else if(key.indexOf("okx") > -1){
			parsedata_okx.put(key,v);
			lasttime_okx = System.currentTimeMillis();
		}

	}

	/**
	 * 刷新redis data
	 */
	private void flush_redis_data(){

		ScheduledExecutorService service= Executors.newSingleThreadScheduledExecutor();
		service.scheduleAtFixedRate(() -> {
			try{
				if(redis != null ){
					if( parsedata_biance.size() >0 && System.currentTimeMillis()-lasttime_binance < expire_millisecond){
						redis.opsForHash().putAll("robot_binance",parsedata_biance);
						rabbitTemplate.convertAndSend("fanout_robot_calc","","binance");
					}
					if( parsedata_bitmex.size() >0 && System.currentTimeMillis()-lasttime_binance < expire_millisecond){
						redis.opsForHash().putAll("robot_bitmex",parsedata_bitmex);
						rabbitTemplate.convertAndSend("fanout_robot_calc","","binance");
					}
					if( parsedata_ftx.size() >0 &&  System.currentTimeMillis()-lasttime_binance < expire_millisecond){
						redis.opsForHash().putAll("robot_ftx",parsedata_ftx);
						rabbitTemplate.convertAndSend("fanout_robot_calc","","ftx");
					}
					if( parsedata_gate.size() >0 &&  System.currentTimeMillis()-lasttime_binance < expire_millisecond ){
						redis.opsForHash().putAll("robot_gate",parsedata_gate);
						rabbitTemplate.convertAndSend("fanout_robot_calc","","gate");
					}
					if( parsedata_mexc.size() >0 && System.currentTimeMillis()-lasttime_binance < expire_millisecond ){
						redis.opsForHash().putAll("robot_mexc",parsedata_mexc);
						rabbitTemplate.convertAndSend("fanout_robot_calc","","mexc");
					}
					if( parsedata_okx.size() >0  &&  System.currentTimeMillis()-lasttime_binance < expire_millisecond){
						redis.opsForHash().putAll("robot_okx",parsedata_okx);
						rabbitTemplate.convertAndSend("fanout_robot_calc","","okx");
					}


				}

			}catch (Exception ex){
				log.error("flush_redis_data error ",ex.getMessage());
			}
		}, 200, 200, TimeUnit.MILLISECONDS);
	}


}
